package edu.ncsu.csc.ip.client.protocol;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.Socket;
import java.util.Date;

import edu.ncsu.csc.ip.client.ClientInfo;
import edu.ncsu.csc.ip.client.RFCBean;
import edu.ncsu.csc.ip.client.RFCIndex;
import edu.ncsu.csc.ip.common.HeaderBean;
import edu.ncsu.csc.ip.common.Log;
import edu.ncsu.csc.ip.common.NetworkUtils;
import edu.ncsu.csc.ip.common.Protocol;
import edu.ncsu.csc.ip.common.serializer.BeanSerializer;

/**
 * Class <code></code>
 * 
 * 
 * 
 * @author Moin Ayazifar <mayazif@ncsu.edu>
 * @author Steven Elliott <sdelliot@ncsu.edu>
 * 
 */

public class ProtocolRFCServerImpl implements Protocol {

	// private State state = State.IDLE;

	private Socket socket;
	private RFCIndex rfcIndex;
	private ClientInfo clientInfo;

	public ProtocolRFCServerImpl(Socket socket, RFCIndex rfcIndex,
			ClientInfo clientInfo) {
		this.setSocket(socket);
		this.rfcIndex = rfcIndex;
		this.clientInfo = clientInfo;
	}

	public static final String OK = "OK";
	public static final String ERROR = "ERROR";
	public static final String GETRFC = "GETRFC-FILE";
	public static final String RFCQUERY = "GETRFC-INDEX";

	/**
	 * @param cookie
	 *            the cookie to set
	 */

	public String parseCommand(String message) {

		return null;

	}

	/**
	 * @param cookie
	 *            the cookie to set
	 */

	public String parseMessage(String message) {
		if (message.toUpperCase().startsWith(GETRFC)) {
			return getRFC(message);
		} else if (message.startsWith(RFCQUERY)) {
			return rfcQuery(message);
		} else {
			return null;
		}
	}

	/**
	 * @param cookie
	 *            the cookie to set
	 */

	public String getRFC(String message) {
		String[] messages = message.split(HEADER_SPLITTER);

		File file;
		BufferedReader fileReader;
		try {

			HeaderBean headerBean = getHeaderBean(messages[0]);

			// /// READ FILE
			StringBuilder fileSb = null;

			fileSb = new StringBuilder();
			// Location of file to read

			file = new File(rfcIndex.getRFCFileName(headerBean.getParameter()));
			fileReader = new BufferedReader(new FileReader(file));
			String line;
			while ((line = fileReader.readLine()) != null)
				fileSb.append(line + "\n");
			fileReader.close();

			return getHeader(GETRFC + " OK", headerBean.getParameter())
					+ HEADER_SPLITTER + fileSb.toString();

		} catch (IOException e) {
			Log.println(clientInfo + "File Not Found!");
			return getHeader(ERROR) + HEADER_SPLITTER
					+ " File Does Not Exist! Message: " + e.getMessage();
		} catch (Exception e) {
			Log.println(clientInfo + "Error occured in sending file. Message: "
					+ e.getMessage());
			return getHeader(ERROR) + HEADER_SPLITTER + e.getMessage();
		}
	}

	/**
	 * @param cookie
	 *            the cookie to set
	 */

	public String rfcQuery(String message) {
		// String[] messages = message.split(HEADER_SPLITTER);
		try {
			// HeaderBean headerBean = getHeaderBean(messages[0]);
			BeanSerializer<RFCBean> rfcSerializer = new BeanSerializer<RFCBean>(
					RFCBean.class);

			return getHeader(RFCQUERY) + HEADER_SPLITTER
					+ rfcSerializer.getString(rfcIndex.mergeGlobalLocalRFC());

		} catch (Exception e) {
			Log.println(clientInfo
					+ "Error occured in sending RFC index. Message: "
					+ e.getMessage());
			return getHeader(ERROR) + HEADER_SPLITTER + e.getMessage();
		}

	}

	private String getHeader(String message) {

		return getHeader(message, null);

	}

	private String getHeader(String message, String parameter) {

		HeaderBean headerBean = new HeaderBean();
		headerBean.setParameter(parameter);
		headerBean.setMessage(message);
		headerBean.setOs(NetworkUtils.getOsName());
		headerBean.setProtocol(PROTOCOL_VERSION);
		headerBean.setDate(new Date());
		headerBean.setAddress(NetworkUtils.getLocalAdress(socket)
				.getHostAddress());
		headerBean.setHostname(NetworkUtils.getLocalAdress(socket)
				.getHostName());
		BeanSerializer<HeaderBean> bSerializer = new BeanSerializer<HeaderBean>(
				HeaderBean.class);
		String headerString = bSerializer.getString(headerBean);
		String headerMessage = headerString.substring(HeaderBean.TRIM_STRING
				.length());
		return headerMessage;

	}

	HeaderBean getHeaderBean(String headerMessage) {

		String headerString = HeaderBean.TRIM_STRING + headerMessage;
		BeanSerializer<HeaderBean> bSerializer = new BeanSerializer<HeaderBean>(
				HeaderBean.class);
		return bSerializer.getBean(headerString);

	}

	/**
	 * @return the socket
	 */
	@Override
	public Socket getSocket() {
		return socket;
	}

	/**
	 * @param socket
	 *            the socket to set
	 */
	@Override
	public void setSocket(Socket socket) {
		this.socket = socket;
	}

	@Override
	public boolean isRFCCommand(String message) {
		return false;
	}

	@Override
	public boolean isFileTransferCommand(String command) {
		return false;
	}

}
